package com.baijia.web.util;

import com.baijia.authentication.handler.exception.UrlMessageException;
import com.baijia.authentication.principal.SimpleWebApplicationServiceImpl;
import com.baijia.common.enums.ResponseStatus;
import com.baijia.services.RegisteredService;
import com.baijia.services.ServicesManager;

import org.apache.commons.lang.StringUtils;

import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;

public class URLUtil {

    private static final String PARAM_PREFIX = "?";
    private static final String SEPARATOR = "&";
    // FIXME 从PassportConfig中取默认登录页
    private static final String ERR_PREFIX = "errCode=";
    private static final String SERVICE_PREFIX = "service=";
    private static final String TICKET_PREFIX = "pp_ticket=";
    private static final String TS = "ts=";

    private static String getErrorMessage(ResponseStatus status) {
        if (status == null) {
            return ERR_PREFIX;
        }
        return ERR_PREFIX + status.getCode();
    }

    private static String getServiceMessage(SimpleWebApplicationServiceImpl service) {
        if (service == null) {
            return SERVICE_PREFIX;
        }
        return SERVICE_PREFIX + service.getOriginalUrl();
    }

    /**
     * 无权限页面
     * 
     * @param request
     * @return
     */
    public static String getNoauthUrl(HttpServletRequest request) {
        return addTS(request.getContextPath() + "/noauth.html");
    }

    /**
     * 登录页面
     * 
     * @param servicesManager
     * @param appId
     * @return
     */
    public static String getLoginAddr(ServicesManager servicesManager, String appId, String defaultUrl) {
        String loginAddr = defaultUrl;
        if (StringUtils.isNotBlank(appId) && servicesManager != null) {
            RegisteredService service = servicesManager.findServiceBy(Integer.valueOf(appId));
            loginAddr = service.getLoginAddr();
        }
        return addTS(loginAddr);
    }

    /**
     * 附带错误信息登录页面
     * 
     * @param servicesManager
     * @param appId
     * @return
     */
    public static String getLoginAddrWithMsg(ServicesManager servicesManager, String appId, UrlMessageException ume,
        String defaultUrl) {
        String loginAddrWithError = defaultUrl;
        if (StringUtils.isNotBlank(appId) && servicesManager != null) {
            RegisteredService service = servicesManager.findServiceBy(Integer.valueOf(appId));
            loginAddrWithError = service.getLoginAddr();
        }

        if (null != ume) {
            if (loginAddrWithError.indexOf("?") != -1) {
                loginAddrWithError =
                    loginAddrWithError + "&code=" + safeUrlEncode(ume.getCode()) + "&msg="
                        + safeUrlEncode(ume.getMessage()) + "&service=" + safeUrlEncode(defaultUrl);
            } else {
                loginAddrWithError =
                    loginAddrWithError + "?code=" + safeUrlEncode(ume.getCode()) + "&msg="
                        + safeUrlEncode(ume.getMessage()) + "&service=" + safeUrlEncode(defaultUrl);
            }

        }

        return addTS(loginAddrWithError);
    }

    /**
     * 附带错误信息登录页面
     * 
     * @param servicesManager
     * @param appId
     * @param status
     * @return
     */
    public static String getLoginAddrWithError(ServicesManager servicesManager, String appId, ResponseStatus status,
        String defaultUrl) {
        String loginAddrWithError = defaultUrl;
        String errMessage = getErrorMessage(status);
        if (StringUtils.isNotBlank(appId) && servicesManager != null) {
            RegisteredService service = servicesManager.findServiceBy(Integer.valueOf(appId));
            loginAddrWithError = service.getLoginAddr();
        }
        return addTS(loginAddrWithError + PARAM_PREFIX + errMessage);
    }

    public static String getLoginAddrWithErrorAndService(ServicesManager servicesManager, String appId,
        ResponseStatus status, SimpleWebApplicationServiceImpl service, String defaultUrl) {
        return addTS(getLoginAddrWithError(servicesManager, appId, status, defaultUrl) + SEPARATOR
            + getServiceMessage(service));
    }

    public static String getValidSTUrl(SimpleWebApplicationServiceImpl service, String ST, String defaultUrl) {
        if (service == null || StringUtils.isBlank(ST)) {
            return defaultUrl;
        }
        if (service.getOriginalUrl().contains(PARAM_PREFIX)) {
            return addTS(service.getOriginalUrl() + SEPARATOR + TICKET_PREFIX + ST);
        }
        return addTS(service.getOriginalUrl() + PARAM_PREFIX + TICKET_PREFIX + ST);
    }

    private static String addTS(String url) {
        if (url.contains(TS)) {
            return url;
        }
        if (url.contains(PARAM_PREFIX)) {
            url += SEPARATOR;
        } else {
            url += PARAM_PREFIX;
        }
        return url + TS + System.currentTimeMillis();
    }

    public static String safeUrlEncode(String param) {
        try {
            return URLEncoder.encode(param, "utf-8");
        } catch (Throwable e) {
            // no op
        }

        return "";
    }

    public static String safeUrlDecode(String param) {
        try {
            return URLDecoder.decode(param, "utf-8");
        } catch (Throwable e) {
            // no op
        }

        return "";
    }

    public static String getLoginUrl(String mobile, String password, String loginUrl) {

        if (loginUrl.contains(PARAM_PREFIX)) {
            return loginUrl + SEPARATOR + "username=" + mobile + SEPARATOR + "password=" + password;
        }
        return loginUrl + PARAM_PREFIX + "username=" + mobile + SEPARATOR + "password=" + password;
    }
}
